package com.lhl.shiro.shiroconfig;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author LHL
 * @date 2018/1/8
 */


public class SystemCacheManager {
    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${cache.token.timeout}")
    private Integer timeout;

    private static final Logger logger = LoggerFactory.getLogger(SystemCacheManager.class);

    public void putToken(String token, String userId) {
        StatelessToken tokenItem = new StatelessToken(token, userId);
        redisTemplate.opsForValue().set((token), tokenItem);
        redisTemplate.expire((token), timeout, TimeUnit.MINUTES);
    }


    public void remove(String token) {
        redisTemplate.delete((token));
    }

    /**
     * 验证token合法性
     *
     * @return true 合法 false 非法
     */
    public boolean validateToken(StatelessToken statelessToken) {
        logger.info("[开始验证 token 与 用户id]");
        StatelessToken token = (StatelessToken) redisTemplate.opsForValue().get((statelessToken.getToken()));
        if (token != null && statelessToken.getPrincipal().equals(token.getPrincipal())) {
            refresh(token);
            return true;
        }
        logger.info("[验证 token 与 userId 失败，访问非法]");
        return false;
    }

    private void refresh(StatelessToken statelessToken) {
        logger.info("[刷新 token:{}]", statelessToken.getToken());
        redisTemplate.opsForValue().set((statelessToken.getToken()), statelessToken);
        redisTemplate.expire((statelessToken.getToken()), timeout, TimeUnit.MINUTES);
    }

    /**
     * 登出
     */
    public void logout(String userId, String tokenStr) {
        logger.info("用户登出，id:{},token:{} ", userId, tokenStr);
        redisTemplate.delete((tokenStr));
        logger.info("[用户 token 全部清理完成] userId={}", userId);
    }

    /**
     * 登出: 同一账户全部登出
     *
     * @param userId 用户id
     */
    public void logoutAll(String userId) {
        Set keys = redisTemplate.keys(("*"));
        Iterator<String> iterator = keys.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            StatelessToken token = (StatelessToken) redisTemplate.opsForValue().get(next);
            if (token.getPrincipal().equals(userId)) {
                redisTemplate.delete(next);
                logger.info("[清除 token] token={},userId={}", token.getToken(), userId);
            }
        }

    }
}
